#coding=utf-8
#suppress 'too many' lines warning
#pylint: disable-msg=C0302
"""
copyright (c) 2009, paketka@gmail.com et. al
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.

    * Neither the name of the <ORGANIZATION> nor the names of its contributors
      may be used to endorse or promote products derived from this software
      without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""

import datetime
import calendar
import StringIO
import re

from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
from django.http import HttpResponse
from django.core.paginator import Paginator
from django.http import Http404
from django.db.models import Q
from django.core.exceptions import ObjectDoesNotExist
from django.utils.translation import ugettext as _

#suppress wildcard import warning
#pylint: disable-msg=W0401
from psp.models import Group, Person, Poll, GroupStats, TermOfOffice, MpVote
from psp.models import MpDayStats, Membership


def get_dates(date, rangeType):
    """
    Accepts date and range parameter.
    returns dateStart, dateEnd tupple for given date and range.
    """
    dateStart = None
    dateEnd = None

    if rangeType == 'den':
        dateStart = date
        dateEnd = None
    elif rangeType == 'tyden':
        #suppress unused variable wd warning
        #pylint: disable-msg=W0612
        (year, week, wd) = date.isocalendar()
        td = datetime.timedelta(days = date.weekday())
        dateStart = date - td
        td = datetime.timedelta(days = 6 - date.weekday())
        dateEnd = date + td
    elif rangeType == 'mesic':
        dateStart = date
        #suppress unused variable wd warning
        #pylint: disable-msg=W0612
        first, last = calendar.monthrange(
                            year = date.year,
                            month = date.month
                    )
        dateEnd = datetime.date(
                        day = last,
                        month = date.month,
                        year = date.year
                    )

    return (dateStart, dateEnd,)


def filter_mp_list(pageObjects, filterExp, attribs = (
                                            u'title',
                                            u'name',
                                            u'surname',
                                            u'titleLast',
                                            u'partyName',
                                            u'divisionName'
                                        )
                                ):
    """
    filters objects from pageObjects set. filterExp is parameter gathered from
    GET. it can have any of form bellow:
        ing pRaha   (will return all persons with ing title from prague)

        mudr karel  (will return all persons with mudr title and name/surname
                    matching to karel)

        libor vlk   (will return all persons who are called libor vlk or vlk
                    libor)

        pavel pavel (will return all persons who are called pavel pavel)

        josef praha (will return all persons who are living in praha or are
                    called josef praha)
        ...

    function will split filterExp to words, and then it will apply each word
    to every following attribute:
        person__title
        person__name
        person__surname
        person__titleLast
        mpClub
        divName

    the resulting lists are cobnined so we get the most accurate set, which
    members match to all criteria.
    """
    def match_attrib(pageObjects, filterExp, attrib):
        """
        Functions performs desired filtering of page object by matching
        object's attribute with filterExp.
            pageObjects - list of page objects
            filterExp   - expression ('ODS', 'Praha' ...)
            attrib      - attribute name (i.e. name, surname, ...)
        Returns list of page objects, which match filter expression
        """
        pattern = re.compile(u'.*' + filterExp + u'.*', re.U | re.I)
        retVal = []
        
        for p in pageObjects:
            t = None
            if hasattr(p, attrib):
                t = getattr(p, attrib)
                if pattern.match(t) != None:
                    retVal.append(p)

        return retVal

    
    for f in filterExp.split(' '):
        matchSet = []
        for a in attribs:
            tmpList = match_attrib(pageObjects, f, a)
            if len(tmpList) > 0:
                matchSet += tmpList

        pageObjects = matchSet

    return pageObjects


def list_persons_json(request, yearStart = None, yearEnd = None):
    """
    Returns data for jqgrid. It lists MPs for given term, which
    is defined by <yearStart, yearEnd>
    """
    pageNo = 1
    rows = 25
    filterExp = ''

    try:
        rows = int(request.GET.get('rows'))
        pageNo = int(request.GET.get('page'))
        filterExp = request.GET.get('filter__exp')
        
        if filterExp == None:
            filterExp = ''
    #suppress 'Exception does not do anything' warning (0704)
    #suppress 'No exception's type specified' warning (0702)
    #pylint: disable-msg=W0704
    except:
        pass#pylint: disable-msg=W0702

    term = None
    if yearStart != None and yearEnd != None:
        term = TermOfOffice.get_term_or_404(yearStart, yearEnd)

    sidx = request.GET.get('sidx')
    sord = request.GET.get('sord')
    desc = (sord != None and sord == 'desc')
    pageObjects = None

    if sidx == None or sidx == '' or sidx == 'person__surname':
        pageObjects = Person.objects.getPersons(desc = desc, term = term)
    elif sidx == 'person__name':
        pageObjects = Person.objects.getPersonsOrderByName(
                                            desc = desc,
                                            term = term
                                        )
    elif sidx == 'person__birthDate':
        pageObjects = Person.objects.getPersonsOrderByAge(
                                            desc = desc,
                                            term = term
                                        )
    elif sidx == 'group__name':
        pageObjects = Person.objects.getPersonsOrderByParty(
                                            desc = desc,
                                            term = term
                                        )
    elif sidx == 'division':
        pageObjects = Person.objects.getPersonsOrderByDivision(
                                            desc = desc,
                                            term = term
                                        )
    elif sidx == 'absences':
        pageObjects = Person.objects.getPersonsOrderByAbsences(
                                            desc = desc,
                                            term = term
                                        )
        
    if filterExp != '':
        pageObjects = filter_mp_list(pageObjects, filterExp)

    paginator = Paginator(pageObjects, rows)
    page = paginator.page(pageNo)
    return render_to_response('persons.json', {
                                    'pageNo' : pageNo,
                                    'pagesTotal' : paginator.num_pages,
                                    'records' : rows,
                                    'page': page,
                                    'today': datetime.date.today(),
                                    'term': term,
                                    },
                                mimetype = 'application/json',
                                context_instance = RequestContext(request)
                            )


#suppress 'Too many arguments' warning (0704)
#pylint: disable-msg=R0913
def group_members_json(request, groupSlug,
    rangeType = None, year = None, month = None, day = None):
    """
    List MPs in particular group for month/week/day. Returns data for jqgrid.
        groupSlug   - defines group
        rangeType   - is one of these:
            den: for day
            tyden: for week
            mesic: for month
        year, month, day are self explaining
    """
    #suppress 'Too many local variables' warning (0704)
    #pylint: disable-msg=R0914
    pageNo = 1
    rows = 25
    filterExp = ''
    group = get_object_or_404(Group, slug = groupSlug)
    try:
        rows = int(request.GET.get('rows'))
        pageNo = int(request.GET.get('page'))
        filterExp = request.GET.get('filter__exp')
        
        if filterExp == None:
            filterExp = ''
    #suppress 'Exception does not do anything' warning (0704)
    #suppress 'No exception type specified' warning (0702)
    #pylint: disable-msg=W0704
    except:
        pass #pylint: disable-msg=W0702

    dateStart = None
    dateEnd = None
    if rangeType != None:
        date = datetime.date(
            year = int(year),
            month = int(month),
            day = int(day)
        )
        dateStart, dateEnd = get_dates(date, rangeType.lower())
    
    sidx = request.GET.get('sidx')
    if sidx == None or sidx == '':
        sidx = 'person__surname'

    sord = request.GET.get('sord')
    desc = sord != None and sord == 'desc'

    pageObjects = []
    if sidx == 'person__birthDate':
        pageObjects = group.getMembersByAge(
            desc = desc,
            dateStart = dateStart,
            dateEnd = dateEnd,
            distinct = False
        )
    elif sidx == 'group__name':
        pageObjects = group.getMembersByParty(
            desc = desc,
            dateStart = dateStart,
            dateEnd = dateEnd,
            distinct = False
        )
    elif sidx == 'division':
        pageObjects = group.getMembersByDivision(
            desc = desc,
            dateStart = dateStart,
            dateEnd = dateEnd,
            distinct = False
        )
    elif sidx == 'absences':
        pageObjects = group.getMembersByAbsences(
            desc = desc,
            dateStart = dateStart,
            dateEnd = dateEnd,
            distinct = False
        )
    elif sidx == 'days':
        pageObjects = group.getMembersByDays(
            desc = desc,
            dateStart = dateStart,
            dateEnd = dateEnd,
            distinct = False
        )
    elif sidx == 'person__surname':
        pageObjects = group.getMembersBySurname(
            desc = desc,
            dateStart = dateStart,
            dateEnd = dateEnd,
            distinct = False
        )
    elif sidx == 'person__name':
        pageObjects = group.getMembersByName(
            desc = desc,
            dateStart = dateStart,
            dateEnd = dateEnd,
            distinct = False
        )

    if filterExp != '':
        attribs = (
            u'title',
            u'name',
            u'surname',
            u'titleLast',
            u'partyName',
            u'divisionName',
            u'post',
        )
        pageObjects = filter_mp_list(pageObjects, filterExp, attribs)

    paginator = Paginator(pageObjects, rows)
    page = paginator.page(pageNo)

    return render_to_response(  'members.json', {
                                'term' : group.term,
                                'pageNo' : pageNo,
                                'pagesTotal' : paginator.num_pages,
                                'records' : rows,
                                'page' : page,
                            },
                            mimetype = 'application/json',
                                context_instance = RequestContext(request)
                            )


#suppress warning 'Unused argument'
#pylint: disable-msg=W0613
def get_group_poll_json(request, groupId, pollId):
    """
    Shows chart of poll resulsts in given group.
    """
    poll = get_object_or_404(Poll, id = int(pollId))
    group = get_object_or_404(Group, id = int(groupId))
    gs = GroupStats.objects.get(group = group, poll = poll)
    pollChart = gs.getResultChart()
    json = u''

    if pollChart == None:
        json = u"{ pollPie : '%s',\npartyPie : ''}" % (
            '<img src="http://127.0.0.1:8000/media/images/neexistuje.png"/>'
        )
        return HttpResponse(json, mimetype = 'application/json')

    if group.type != 'KLUB':
        partyPie = group.getPartyPie(poll.date)
        if partyPie == None:
            json = u"{ pollPie : '%s',\npartyPie : '' }" % pollChart.img()
        else:
            json = u"{ pollPie : '%s',\npartyPie : '%s' }" % (
                    pollChart.img(), partyPie.img()
                )
    elif pollChart:
        json = u"{ pollPie : '%s',\npartyPie : '' }" % pollChart.img()
    else:
        json = u"{ pollPie : '',\npartyPie : '' }"

    return HttpResponse(json, mimetype = 'application/json')


def get_polls_in_group(request, groupId, pollId):
    """
    Returns jqgrid data. it is a list of MPs extended by each MP's vote in
    given poll.
    """
    #suppress 'Too many local variables' warning
    #pylint: disable-msg=R0914
    #suppress 'Too many branches' warning
    #pylint: disable-msg=R0912
    def strcmp(a, b):
        """
        Function, which compares two groups (a, b) by result argument,
        which is a string. It's used as a sort() compare operator.
        """
        if a.result < b.result:
            return -1
        elif a.result > b.result:
            return 1
        else:
            return 0


    group = get_object_or_404(Group, id = int(groupId))
    poll = get_object_or_404(Poll, id = pollId)
    pageNo = 1
    rows = 25
    filterExp = ''
    try:
        rows = int(request.GET.get('rows'))
        pageNo = int(request.GET.get('page'))
        filterExp = request.GET.get('filter__exp')
        
        if filterExp == None:
            filterExp = ''
    #suppress 'Exception does not do anything' warning (0704)
    #suppress 'No exception type specified' warning (0702)
    #pylint: disable-msg=W0704
    except:
        pass #pylint: disable-msg=W0702

    sidx = request.GET.get('sidx')
    if sidx == None or sidx == '':
        sidx = 'surname'

    knownSidx = [ 
        'surname',
        'name',
        'party',
        'area',
        'result',
    ]
    if not sidx in knownSidx:
        sidx = 'surname'

    sord = request.GET.get('sord')
    desc = sord != None and sord == 'desc'
    
    pageObjects = []
    if sidx == 'party':
        pageObjects = group.getMembersByParty(
                            desc = desc,
                            dateStart = poll.date
                        )
    elif sidx == 'area':
        pageObjects = group.getMembersByDivision(
                            desc = desc,
                            dateStart = poll.date
                        )
    elif sidx == 'surname':
        pageObjects = group.getMembersBySurname(
                            desc = desc,
                            dateStart = poll.date
                        )
    elif sidx == 'name':
        pageObjects = group.getMembersByName(
                            desc = desc,
                            dateStart = poll.date
                        )
    else:
        pageObjects = group.getMembersBySurname(
                            desc = desc,
                            dateStart = poll.date
                        )

    if filterExp != '':
        attribs = (
            u'title',
            u'name',
            u'surname',
            u'titleLast',
            u'divisionName',
            u'post',
            u'partyName',
        )
        pageObjects = filter_mp_list(pageObjects, filterExp, attribs)
        
    for mp in pageObjects:
        try:
            mp.result = MpVote.objects.get(person = mp, poll = poll).getResult()
        except ObjectDoesNotExist:
            pass

    if sidx == 'result':
        if desc:
            pageObjects.sort(strcmp)
            pageObjects.reverse()
        else:
            pageObjects.sort(strcmp)

    paginator = Paginator(pageObjects, rows)
    page = paginator.page(pageNo)

    return render_to_response(  'poll_groups.json', {
                                    'pageNo' : pageNo,
                                    'pagesTotal' : paginator.num_pages,
                                    'records' : rows,
                                    'page' : page,
                                    'term' : poll.meeting.term,
                                },
                                mimetype = 'application/json',
                                context_instance = RequestContext(request)
                            )


def filter_procedural(qs, request):
    """
    If request is request object. If request containse filterProcedural=1
    parameter, then function applies  procedural filter to query set 'qs'.
    Otherwise it returns queryset untouched.

    expected queryset must be Poll class queryset
    returns queryset
    """
    filterProcedural = False
    try:
        tmp = request.GET.get('filterProcedural')
        filterProcedural = (tmp != None and tmp == '1')
    #suppress 'Exception does not do anything' warning (0704)
    #suppress 'No exception type specified' warning (0702)
    #pylint: disable-msg=W0704
    except:
        pass #pylint: disable-msg=W0702

    retVal = qs
    if filterProcedural:
        retVal = qs.filter(~Q(name__iregex = '.*Procedurální hlasování'))

    return retVal


def get_polls_in_day(request, year, month, day):
    """
    Returns jqgrid data with list of polls for given day.
    """
    pageNo = 1
    rows = 25
    filterExp = ''
    try:
        rows = int(request.GET.get('rows'))
        pageNo = int(request.GET.get('page'))

        filterExp = request.GET.get('filter__exp')
        if filterExp == None:
            filterExp = ''
    #suppress 'Exception does not do anything' warning (0704)
    #suppress 'No exception type specified' warning (0702)
    #pylint: disable-msg=W0704
    except:
        pass #pylint: disable-msg=W0702

    date = datetime.datetime(
                    year = int(year),
                    month = int(month),
                    day = int(day)
                )

    polls = Poll.objects.filter(date = date)
    polls = filter_procedural(polls, request)

    if filterExp != '':
        regex = u''
        for i in filterExp.split(' '):
            regex = '.*' + i + '.*'
        polls = polls.filter(
                            date = date,
                            name__iregex = regex
                        ).order_by('pollId')

    paginator = Paginator(polls, rows)
    page = paginator.page(pageNo)

    return render_to_response(  'polls_in_day.json', {
                                    'pageNo' : pageNo,
                                    'pagesTotal' : paginator.num_pages,
                                    'records' : rows,
                                    'page' : page,
                                },
                                mimetype = 'application/json',
                                context_instance = RequestContext(request)
                            )


#suppress warning 'Unused argument'
#pylint: disable-msg=W0613
def get_meetings_in_month(request, year, month):
    """
    Returns data for datepicker, so it can highlight a day, when there were
    meetings.
    """
    polls = Poll.objects.filter(
                date__month = int(month),
                date__year = int(year)
            ).distinct('date').order_by('date')

    #suppress 'Unused variable' warning
    #pylint: disable-msg=W0612
    dateMap = [0 for i in range(32)]
    for p in polls:
        dateMap[p.date.day] = 1

    buf = StringIO.StringIO()
    buf.write(dateMap)
    json = buf.getvalue()
    buf.close()

    return HttpResponse(json, mimetype = 'application/json')


def get_votes_common(request, mp, date, votes):
    """
    Returns json data for jqgrid. It lists results for particular MP compared
    with result of MP's party club.
    It's backend for get_aye()/get_nay()/get_refrains()
    """
    pageNo = 1
    rows = 25
    try:
        rows = int(request.GET.get('rows'))
        pageNo = int(request.GET.get('page'))
    #suppress 'Exception does not do anything' warning (0704)
    #suppress 'No exception type specified' warning (0702)
    #pylint: disable-msg=W0704
    except:
        pass #pylint: disable-msg=W0702

    paginator = Paginator(votes, rows)
    page = paginator.page(pageNo)
    
    pageData = []
    for i in page.object_list:
        record = {}
        record['vote'] = i
        groupResult = GroupStats.objects.get(
                                        poll = i.poll,
                                        group = mp.getPartyClub(date)
                                    ).result
    
        if i.result == groupResult:
            record['loyal'] = _('S klubem')
        else:
            record['loyal'] = _('Proti klubu')
        
        pageData.append(record)

    return render_to_response(  'mp_votes.json', {
                                    'pageNo' : pageNo,
                                    'pagesTotal' : paginator.num_pages,
                                    'records' : rows,
                                    'page' : pageData,
                                },
                                mimetype = 'application/json',
                                context_instance = RequestContext(request)
                            )


def filter_procedural_mpvote(qs, request):
    """
    If request is request object. If request containse filterProcedural=1
    parameter, then function applies  procedural filter to query set 'qs'.
    Otherwise it returns queryset untouched.

    expected queryset must be MpVote class queryset
    returns queryset
    """
    filterProcedural = False
    try:
        tmp = request.GET.get('filterProcedural')
        filterProcedural = (tmp != None and tmp == '1')
    #suppress 'Exception does not do anything' warning (0704)
    #suppress 'No exception type specified' warning (0702)
    #pylint: disable-msg=W0704
    except:
        pass #pylint: disable-msg=W0702

    retVal = qs
    if filterProcedural:
        retVal = qs.filter(~Q(
                    poll__name__iregex = '.*Procedurální hlasování'
                ))
        
    return retVal


def get_aye(request, mpSlug, year, month, day):
    """
    Returns jqgrid data with 'AYE' poll results for mp and day.
    """
    date = datetime.date(
                day = int(day),
                month = int(month),
                year = int(year)
            )
    mp = get_object_or_404(Person, slug = mpSlug)
    votes = MpVote.objects.filter( 
                                person = mp,
                                result = 'A',
                                poll__date = date
                        )

    votes = filter_procedural_mpvote(votes, request)
    return get_votes_common(request, mp, date, votes)


def get_nay(request, mpSlug, year, month, day):
    """
    Returns jqgrid data with 'NAY' poll results for mp and day.
    """
    date = datetime.date(
                day = int(day),
                month = int(month),
                year = int(year)
            )
    mp = get_object_or_404(Person, slug = mpSlug)
    votes = MpVote.objects.filter( 
                                person = mp,
                                result = 'N',
                                poll__date = date
                        )

    votes = filter_procedural_mpvote(votes, request)
    return get_votes_common(request, mp, date, votes)


def get_refrains(request, mpSlug, year, month, day):
    """
    Returns jqgrid data with 'REFRAINS' poll results for mp and day.
    """
    date = datetime.date(
                day = int(day),
                month = int(month),
                year = int(year)
            )
    mp = get_object_or_404(Person, slug = mpSlug)
    votes = MpVote.objects.filter(
                                person = mp,
                                result = 'Z',
                                poll__date = date
                        )

    votes = filter_procedural_mpvote(votes, request)
    return get_votes_common(request, mp, date, votes)


def get_absences(request, mpSlug, year, month, day):
    """
    Returns jqgrid data with 'ABSENCES' poll results for mp and day.
    """
    date = datetime.date(
                day = int(day),
                month = int(month),
                year = int(year)
            )
    mp = get_object_or_404(Person, slug = mpSlug)

    votes = MpVote.objects.filter(
                Q(person = mp),
                Q(poll__date = date),
                ~Q(result = 'A'),
                ~Q(result = 'N'),
                ~Q(result = 'Z')
            )

    votes = filter_procedural_mpvote(votes, request)
    return get_votes_common(request, mp, date, votes)


def get_mp_accordance(request, mpId, groupId, yearStart, monthStart, dayStart,
    noActive, yearEnd = None, monthEnd = None, dayEnd = None):
    """
    Returns loyal pie chart for mp, group in given term
    """
    #suppress 'Too many local variables' warning (0704)
    #pylint: disable-msg=R0914
    dateStart = datetime.date(
        year = int(yearStart),
        month = int(monthStart),
        day = int(dayStart)
    )

    dateEnd = None
    if yearEnd != None:
        dateEnd = datetime.date(
            year = int(yearEnd),
            month = int(monthEnd),
            day = int(dayEnd)
        )

    mp = get_object_or_404(Person, id = int(mpId))
    group = get_object_or_404(Group, id = int(groupId))

    accordance, activeAccordance = mp.getAccordanceCharts(
                                    group, dateStart, dateEnd
                                )
    if noActive == '1':
        activeAccordance = None
    partyPie = None

    if group.type != 'KLUB':
        partyPie = group.getPartyPie()
        partyPie.size(330, 80)
    
    return render_to_response('accord_charts.json', {
                                    'accordance' : accordance,
                                    'activeAccordance' : activeAccordance,
                                    'partyPie' : partyPie,
                                },
                                mimetype = 'application/json',
                                context_instance = RequestContext(request)
                            )


def get_loyal_pie(request, rangeType, mpSlug, groupId, year, month, day):
    """
    Returns loyal pie chart for mp, group in given term
    """
    dateStart, dateEnd = get_dates(
            datetime.date(  year = int(year),
                            month = int(month),
                            day = int(day)
                        ),
            rangeType = rangeType.lower()
        )
    mp = get_object_or_404(Person, slug = mpSlug)
    group = get_object_or_404(Group, id = int(groupId))
    
    if group.type == 'KLUB':
        json = "'<img src=\"%s\"/>'" % (
                                        mp.getLoyalChartForDates(
                                                dateStart = dateStart,
                                                dateEnd = dateEnd,
                                                group = group),
                                    )
    else:
        partyPie = group.getPartyPie(
                            dateStart = dateStart,
                            dateEnd = dateEnd
                        )
        partyPie.size(330, 80)
        json = "'<img src=\"%s\"/><img src=\"%s\"/>'" % (
                    mp.getLoyalChartForDates(
                                dateStart = dateStart,
                                dateEnd = dateEnd,
                                group = group
                    ),
                    partyPie
                )

    return HttpResponse(json, mimetype = 'application/json')


def get_group_common(request, groupStats):
    """
    Returns json data for jqgrid. json data show the poll results for group.
    The function is backend for get_group_aye(), get_group_nay(), ...
    """
    pageNo = 1
    rows = 25
    try:
        rows = int(request.GET.get('rows'))
        pageNo = int(request.GET.get('page'))
    #suppress 'Exception does not do anything' warning (0704)
    #suppress 'No exception type specified' warning (0702)
    #pylint: disable-msg=W0704
    except:
        pass #pylint: disable-msg=W0702

    paginator = Paginator(groupStats, rows)
    page = paginator.page(pageNo)
    
    return render_to_response(  'group_votes.json', {
                                    'pageNo' : pageNo,
                                    'pagesTotal' : paginator.num_pages,
                                    'records' : rows,
                                    'page' : page,
                                },
                                mimetype = 'application/json',
                                context_instance = RequestContext(request)
                            )

def get_group_aye(request, groupSlug, year, month, day):
    """
    Returns jqgrid data with AYE poll rsults for given group and day
    """
    group = get_object_or_404(Group, slug = groupSlug)
    date = datetime.date(
                    year = int(year),
                    month = int(month),
                    day = int(day)
                )
    groupStats = []
    polls = Poll.objects.filter(date = date)
    polls = filter_procedural(polls, request)
    for p in polls:
        gs = None
        try:
            gs = get_object_or_404(GroupStats, group = group, poll = p)
        except ObjectDoesNotExist:
            continue

        if gs.getResult() != 'Pro':
            continue
    
        groupStats.append(gs)

    return get_group_common(request, groupStats)


def get_group_nay(request, groupSlug, year, month, day):
    """
    Returns jqgrid data with NAY poll rsults for given group and day
    """
    group = get_object_or_404(Group, slug = groupSlug)
    date = datetime.date(
                    year = int(year),
                    month = int(month),
                    day = int(day)
                )
    groupStats = []
    polls = Poll.objects.filter(date = date)
    polls = filter_procedural(polls, request)
    for p in polls:
        gs = None
        try:
            gs = get_object_or_404(GroupStats, group = group, poll = p)
        except ObjectDoesNotExist:
            continue

        if gs.getResult() != 'Proti':
            continue

        groupStats.append(gs)

    return get_group_common(request, groupStats)


def get_group_refrains(request, groupSlug, year, month, day):
    """
    Returns jqgrid data with REFRAINS poll rsults for given group and day
    """
    group = get_object_or_404(Group, slug = groupSlug)
    date = datetime.date(
                    year = int(year),
                    month = int(month),
                    day = int(day)
                )
    groupStats = []
    polls = Poll.objects.filter(date = date)
    polls = filter_procedural(polls, request)
    for p in polls:
        gs = None
        try:
            gs = get_object_or_404(GroupStats, group = group, poll = p)
        except ObjectDoesNotExist:
            continue

        if gs.getResult() != u'Zrželi':
            continue

        groupStats.append(gs)

    return get_group_common(request, groupStats)


def get_group_absences(request, groupSlug, year, month, day):
    """
    Returns jqgrid data with ABSENCES poll rsults for given group and day
    """
    group = get_object_or_404(Group, slug = groupSlug)
    date = datetime.date(
                    year = int(year),
                    month = int(month),
                    day = int(day)
                )
    groupStats = []
    polls = Poll.objects.filter(date = date)
    polls = filter_procedural(polls, request)
    for p in polls:
        gs = None
        try:
            gs = get_object_or_404(GroupStats, group = group, poll = p)
        except ObjectDoesNotExist:
            continue

        if gs.getResult() != u'Chyběli':
            continue

        groupStats.append(gs)

    return get_group_common(request, groupStats)


def get_accordance_pie_chart_common(request,
    groupId, otherGroupId, dateStart = None, dateEnd = None):
    """
    returns poll result accordance for group and other group. Groups are
    specified by their ids. The poll result accordance is computed for
    given pill set (pollQS argument). This is a backend function for
    get_group_accordance(), get_day_accordance_pie_chart_for_group(),
    """
    group = get_object_or_404(Group, id = int(groupId))
    otherGroup = get_object_or_404(Group, id = int(otherGroupId))

    if dateStart == None and dateEnd == None:
        polls = Poll.objects.filter(meeting__term = group.term).order_by('date')
        dateStart = polls[0].date
        dateEnd = polls[len(polls) - 1].date
        if dateStart == dateEnd:
            dateEnd = None
        
    loyalChart = group.getAccordanceWithGroup(  otherGroup,
                                                dateStart = dateStart,
                                                dateEnd = dateEnd
                                            )

    if loyalChart == None:
        raise Http404

    if otherGroup.type == 'KLUB':
        json = u"{ loyalChart : '%s',\n partyPie: 'null' }" % loyalChart.img()
    else:
        partyPie = otherGroup.getPartyPie()
        partyPie.size(330, 80)
        json = u"{ loyalChart : '%s',\n partyPie: '%s' }"  % (
                                        loyalChart.img(),
                                        partyPie.img()
                                    )
    
    return HttpResponse(json, mimetype = 'application/json')    


def get_group_accordance(request, groupId, otherGroupId,
    rangeType = None, year = None, month = None, day = None):
    """
    Returns json data with pie chart poll accordance for group with other group in
    particular term.
        groupSlug - group we are examining
        otherGroupSlug - group we want to view accordance with
        termId - id of term
    """

    if rangeType == None:
        return get_accordance_pie_chart_common(request, groupId, otherGroupId)
    else:
        date = datetime.date(
            year = int(year),
            month = int(month),
            day = int(day)
        )
        dateStart, dateEnd = get_dates(date, rangeType.lower())
        return get_accordance_pie_chart_common(
            request,
            groupId,
            otherGroupId,
            dateStart,
            dateEnd
        )
    


def get_day_accordance_pie_chart_for_group(
                                request,
                                groupId,
                                otherGroupId, 
                                year,
                                month,
                                day
                            ):
    """
    Same as get_term_accordance_pie_chart_for_group(), but this time for any
    given day.
    """
    date = datetime.date(
                    day = int(day),
                    month = int(month),
                    year = int(year)
                )
    polls = Poll.objects.filter(date = date)

    return get_accordance_pie_chart_common(
                request, groupId, otherGroupId, polls
            )


def get_rebels(request, rangeType, year, month, day):
    """
    Implements json view for rebels, parameters are
        rangeType - expected values are:
            den     for day view
            tyden   for week view
            mesic   for month view
        year, month, day - day we are interested in

    renders json data for rebels grid.
    """
    #suppress 'Too many local variables' warning (0704)
    #pylint: disable-msg=R0914
    pageNo = 1
    rows = 25
    filterExp = ''

    filterActive = False
    try:
        tmp = request.GET.get('filterActive')
        filterActive = (tmp != None and tmp == '1')
    #suppress 'Exception does not do anything' warning (0704)
    #suppress 'No exception type specified' warning (0702)
    #pylint: disable-msg=W0704
    except:
        pass #pylint: disable-msg=W0702
    
    validShortRanges = (
        'den',
        'tyden',
        'mesic',
    )

    rangeType = rangeType.lower()

    if rangeType == '':
        rangeType = 'den'

    if not rangeType in validShortRanges:
        raise Http404

    try:
        rows = int(request.GET.get('rows'))
        pageNo = int(request.GET.get('page'))
        filterExp = request.GET.get('filter__exp')
        
        if filterExp == None:
            filterExp = ''
    #suppress 'Exception does not do anything' warning (0704)
    #suppress 'No exception type specified' warning (0702)
    #pylint: disable-msg=W0704
    except:
        pass #pylint: disable-msg=W0702

    dateStart, dateEnd = get_dates(
        date = datetime.date(   year = int(year),
                                month = int(month),
                                day = int(day)
                            ),
        rangeType = rangeType.lower()
    )
                    
    if dateStart == None and dateEnd == None:
        raise Http404

    sidx = request.GET.get('sidx')
    sord = request.GET.get('sord')
    desc = (sord != None and sord == 'desc')

    pageObjects = None

    colname = ''
    colname = sidx.lower().replace('__', '.')
    validColnames = (
        'person.surname',
        'person.name',
        'same'
    )
    if not colname in validColnames:
        colname = 'same'

    pageObjects = Person.objects.getRebels( dayStart = dateStart,
                                            dayEnd = dateEnd,
                                            desc = desc,
                                            colName = colname
                                    )
    if filterExp != '':
        pageObjects = filter_mp_list(pageObjects, filterExp)

    paginator = Paginator(pageObjects, rows)
    page = paginator.page(pageNo)
    return render_to_response('rebels.json', {
                                    'rangeType' : rangeType,
                                    'pageNo' : pageNo,
                                    'pagesTotal' : paginator.num_pages,
                                    'records' : rows,
                                    'page': page,
                                    'today': datetime.date.today(),
                                    'active' : filterActive,
                                    },
                                mimetype = 'application/json',
                                context_instance = RequestContext(request)
                            )


def get_slackers(request, rangeType, year, month, day):
    """
    Implements json view for slackers, parameters are
        rangeType - expected values are:
            den     for day view
            tyden   for week view
            mesic   for month view
        year, month, day - day we are interested in

    renders data for slackers grid.
    """
    #suppress 'Too many local variables' warning (0704)
    #pylint: disable-msg=R0914
    pageNo = 1
    rows = 25
    filterExp = ''
    dateStart = None
    dateEnd = None
    
    rangeType = rangeType.lower()

    if rangeType == '':
        rangeType = 'den'

    try:
        rows = int(request.GET.get('rows'))
        pageNo = int(request.GET.get('page'))
        filterExp = request.GET.get('filter__exp')
        
        if filterExp == None:
            filterExp = ''
    #suppress 'Exception does not do anything' warning (0704)
    #suppress 'No exception type specified' warning (0702)
    #pylint: disable-msg=W0704
    except:
        pass #pylint: disable-msg=W0702

    sidx = request.GET.get('sidx')
    sord = request.GET.get('sord')
    desc = (sord != None and sord == 'desc')

    pageObjects = None

    dateStart, dateEnd = get_dates(
        date = datetime.date(   year = int(year),
                                month = int(month),
                                day = int(day)
                            ),
        rangeType = rangeType.lower()
    )
    
    if dateStart == None and dateEnd == None:
        raise Http404

    colname = ''
    colname = sidx.lower().replace('__', '.')
    validColnames = {
        'person.surname' : 'personSurname',
        'person.name' : 'personName',
        'totalAbsences' : 'totalAbsences'
    }
    if not colname in validColnames.keys():
        colname = 'totalAbsences'
    else:
        colname = validColnames[colname]

    pageObjects = Person.objects.getSlackers(   dayStart = dateStart,
                                            dayEnd = dateEnd,
                                            desc = desc,
                                            colName = colname
                                    )
    if filterExp != '':
        pageObjects = filter_mp_list(pageObjects, filterExp)

    paginator = Paginator(pageObjects, rows)
    page = paginator.page(pageNo)
    return render_to_response('slackers.json', {
                                    'rangeType' : rangeType,
                                    'pageNo' : pageNo,
                                    'pagesTotal' : paginator.num_pages,
                                    'records' : rows,
                                    'page': page,
                                    },
                                mimetype = 'application/json',
                                context_instance = RequestContext(request)
                            )



def get_accordance_np(request):
    """
    This view returns html page fragment with accordance chart for
    http://www.nasipolitici.cz site. All arguments are passed as URL
    parameters. The web page may pass these parameters:
        width   (optional)
        height  (optional)
        title   (optional)
    date range for chart can be specified in two ways:
        date    argument in format (d-m-y)
        rangeType argument, which should be one of these:
            den for day
            tyden for week
            mesic for month
            year for range
    the second way to define a date range is to pass two arguments:
        dateStart
        dateEnd
    expected date format for these two is d-m-y
    mandatory arguments are:
        groupId
        personId
    these two must match the ID's from psp.cz site

    Returns HTTP response with json data.
    """
    try:
        width = int(request.GET.get('width', 330))
        height = int(request.GET.get('height', 80))
    except ValueError:
        width = 330
        height = 80

    rangeType = request.GET.get('rangeType', None)
    title = request.GET.get('title', None)
    dateStart = None
    dateEnd = None

    if rangeType:
        try:
            day, month, year = request.GET.get('date').split('-')
            date = datetime.date(
                    day = int(day),
                    month = int(month),
                    year = int(year)
                )
            dateStart, dateEnd = get_dates(date, rangeType)
            
        except (KeyError, ValueError, AttributeError):
            raise Http404
    else:
        try:
            day, month, year = request.GET.get('dateStart').split('-')
            dateStart = datetime.date(
                    day = int(day),
                    month = int(month),
                    year = int(year)
                )
            day, month, year = request.GET.get('dateEnd').split('-')
            dateEnd = datetime.date(
                    day = int(day),
                    month = int(month),
                    year = int(year)
                )
        except (KeyError, ValueError, AttributeError):
            pass

    group = None
    mp = None
    try:
        groupId = request.GET.get('groupId')
        group = get_object_or_404(Group, groupId = groupId)
    except KeyError:
        raise Http404

    try:
        personId = request.GET.get('personId')
        mp = get_object_or_404(Person, mpId = personId)
    except KeyError:
        raise Http404

    accordance, activeAccordance = mp.getAccordanceCharts(
                                    group = group,
                                    dateStart = dateStart,
                                    dateEnd = dateEnd
                                )
    if accordance == None:
        raise Http404

    accordance.size(width, height)
    if title != None:
        accordance.title(title)

    return render_to_response('accord_charts.jsonp', {
                                    'accordance' : accordance,
                                    'jsonpCbk' : request.GET.get('callback', ''),
                                },
                                mimetype = 'application/json',
                                context_instance = RequestContext(request)
                            )


def get_absences_np(request):
    """
    This view returns html page fragment with absences chart for
    http://www.nasipolitici.cz site. All arguments are passed as URL
    parameters.  The web page may pass these parameters:
        width   (optional)
        height  (optional)
        title   (optional)
    date range for chart can be specified in two ways:
        date    argument in format (d-m-y)
        rangeType argument, which should be one of these:
            den for day
            tyden for week
            mesic for month
            year for range
    the second way to define a date range is to pass two arguments:
        dateStart
        dateEnd
    expected date format for these two is d-m-y
    mandatory argument is:
        personId
    these two must match the ID's from psp.cz site

    Returns HTTP response with json data.
    """

    try:
        width = int(request.GET.get('width', 330))
        height = int(request.GET.get('height', 80))
    except ValueError:
        width = 330
        height = 80

    rangeType = request.GET.get('rangeType', None)
    title = request.GET.get('title', None)
    termId = request.GET.get('termId', None)

    dateStart = None
    dateEnd = None

    mp = None
    try:
        personId = request.GET.get('personId')
        mp = get_object_or_404(Person, mpId = personId)
    except KeyError:
        raise Http404

    if rangeType:
        try:
            day, month, year = request.GET.get('date').split('-')
            date = datetime.date(
                    day = int(day),
                    month = int(month),
                    year = int(year)
                )
            dateStart, dateEnd = get_dates(date, rangeType)
            
        except (KeyError, ValueError, AttributeError):
            raise Http404
    elif termId:
        try:
            term = get_object_or_404(TermOfOffice, id = int(termId))
            mships = Membership.objects.filter(
                        group__term = term,
                        person = mp
                    ).order_by('-start')
            if len(mships) == 0:
                raise Http404
            dateStart = mships[0].start
        
            mships = Membership.objects.filter(
                        group__term = term,
                        person = mp,
                        end = None)
            if len(mships) == 0:
                mships = Membership.objects.filter(
                            group__term = term,
                            person = mp
                        ).order_by('-end')
                if len(mships) == 0:
                    raise Http404
                dateEnd = mships[0].end
            else:
                dateEnd = datetime.date.today()
            
        except ValueError:
            raise Http404
    else:
        try:
            day, month, year = request.GET.get('dateStart').split('-')
            dateStart = datetime.date(
                    day = int(day),
                    month = int(month),
                    year = int(year)
                )
            day, month, year = request.GET.get('dateEnd').split('-')
            dateEnd = datetime.date(
                    day = int(day),
                    month = int(month),
                    year = int(year)
                )
            
        except (KeyError, ValueError, AttributeError):
            raise Http404

    dayStats = MpDayStats.objects.getStatsForRange(
        mp = mp,
        dateStart = dateStart,
        dateEnd = dateEnd
    )

    if dayStats == None:
        raise Http404

    absences = dayStats.votes.getPresenceChart()

    if absences == None:
        raise Http404

    absences.size(width, height)
    if title != None:
        absences.title(title)
    else:
        title = u'Nepřítomnost %s %s' % (mp.name, mp.surname, )
        absences.title(title)

    return render_to_response('absences_chart.jsonp', {
                                    'absences' : absences,
                                    'jsonpCbk' : request.GET.get('callback', ''),
                                },
                                mimetype = 'application/json',
                                context_instance = RequestContext(request)
                            )
